const mongoose = require("mongoose");
const { skipChar } = require("../../db/common/common");
const { LawItem } = require("../../schema/lawSchema");

/**
 * 多元词组拆分
 * @param {*} str
 * @returns
 */
function multiplePhraseSplit(str) {
  const strArr = [];
  for (let i = 0; i < str.length; i++) {
    for (let j = i + 1; j <= str.length; j++) {
      if (skipChar.includes(str[i]) || skipChar.includes(str[j - 1])) {
        break;
      }
      let subStr = str.slice(i, j);
      strArr.push(subStr);
    }
  }
  return strArr;
}

/**
 * 拼接字符串
 * @param {*} strArr
 */
function splicing(strArr) {
  let whiteboardStr = "";
  strArr.forEach((str, index) => {
    if (index === strArr.length - 1) {
      whiteboardStr += str;
    } else {
      whiteboardStr += str + " ";
    }
  });
  return whiteboardStr;
}

/**
 * 修复索引冲突
 * @param {*} model 用于搜索的模型实例
 */
async function fixIndexConfict(model) {
  //获取现有索引
  const indexes = await model.collection.indexes();
  //查找是否有冲突的索引
  const confictIndex = indexes.find((index) => {
    return index.key && index.key._fts === "text" && index.key._ftsx === 1;
  });
  //删除冲突的索引
  if (confictIndex) {
    await model.collection.dropIndex(confictIndex.name);
  }
}

/**
 * 创建索引
 * @param {*} model 用于搜索的模型实例
 * @param {Array} exclusions 排除的字段 (默认值为没有排除)
 */
async function createFullTextIndex(model, exclusions = []) {
  if (!(model.schema instanceof mongoose.Schema)) {
    throw new Error("传入的 Schema 不符合 mongoose Schema 规范");
  }

  fixIndexConfict(model);

  const dataAttributes = Object.keys(model.schema.obj); //获取数据模型的属性
  const obj = {}; //创建空白对象
  dataAttributes.forEach((att) => {
    const schemaType = model.schema.path(att);
    if (schemaType.instance === "Array" && schemaType.schema) {
      const nestedAttrs = Object.keys(schemaType.schema.paths);
      nestedAttrs.forEach((nestedAtt) => {
        if (!exclusions.includes(`${att}.${nestedAtt}`)) {
          obj[`${att}.${nestedAtt}`] = "text";
        }
      });
    } else if (!exclusions.includes(att)) {
      obj[att] = "text";
    }
  });

  console.log(obj);
  // 创建索引
  await model.collection.createIndex({ ...obj }, { default_language: "none" });
}

/**
 * 获取从当前节点到根节点的所有节点
 * @param {*} item
 * @param {*} path 到根节点的路径
 * @returns
 */
async function getSearchPath(item, path, allItemsMap) {
  path.push(item);
  if (!item.parent || item.type === "law") {
    return;
  }
  // 使用缓存查找父项
  const parItem = allItemsMap[item.parent];
  if (parItem) {
    await getSearchPath(parItem, path, allItemsMap);
  }
}

/**
 * 获取搜索到的法律的根节点
 * @param {*} realDocuments 真实的lawItem数据
 */
async function getSearchedRoots(realDocuments) {
  const searchedRoots = {};

  // 获取所有的 LawItem 数据并构建一个Map
  const allItems = await LawItem.find({});
  const allItemsMap = {};
  allItems.forEach((item) => {
    allItemsMap[item._id] = item;
  });

  await Promise.all(
    realDocuments.map(async (item) => {
      const searchPath = [];
      await getSearchPath(item, searchPath, allItemsMap);
      const searchedRootElem = searchPath[searchPath.length - 1].title;

      if (!searchedRoots[searchedRootElem]) {
        searchedRoots[searchedRootElem] = [];
      }
      searchedRoots[searchedRootElem].push(searchPath);
    })
  );

  return searchedRoots;
}

/**
 * 表达项筛选
 * @param {*} form 传入的表单
 */
function formItemFilter(form) {
  // 获取表单项的所有属性
  const formKeys = Object.keys(form);
  // 筛选标准
  const filterCriteria = {};
  for (let key of formKeys) {
    // 如果该属性没有填写就跳过
    if (
      form[key] === undefined ||
      form[key].length <= 0 ||
      form[key] === "不限"
    ) {
      continue;
    }
    // 全文搜索 (先到law中筛选符合条件的法律的id，然后再searchRoot进行id的比对)
    // 标题搜索 (直接到law中筛选)
    if (key === "publishStartDate") {
      filterCriteria.publishedAt = { $gte: new Date(form[key]) };
    } else if (key === "publishEndDate") {
      filterCriteria.publishedAt = {
        ...filterCriteria.publishedAt,
        $lte: new Date(form[key]),
      };
    } else {
      filterCriteria[key] = form[key];
    }
  }
  return filterCriteria;
}

/**
 * 获取搜索状态
 * @param {*} keywords
 */
function getSearchCondition(keywords, lawIds = []) {
  const searchCondition = { $text: { $search: keywords } };
  if (lawIds.length > 0) {
    searchCondition._id = { $in: lawIds };
  }
  return searchCondition;
}

/**
 * 可选参数有效性
 * @param {*} form
 * @param {object} root Law中的项
 */
function optionalParamValidity(form, root) {
  let dateValid;
  if (form.publishStartDate && form.publishEndDate) {
    dateValid =
      new Date(form.publishStartDate) < root.publishedAt &&
      new Date(form.publishEndDate) > root.publishedAt;
    // console.log(1, dateValid);
  } else if (form.publishStartDate && !form.publishEndDate) {
    dateValid = new Date(form.publishStartDate) < root.publishedAt;
    // console.log(2, dateValid);
  } else if (!form.publishStartDate && form.publishEndDate) {
    dateValid = new Date(form.publishEndDate) > root.publishedAt;
    // console.log(3, dateValid);
  } else {
    dateValid = true; //如果没有时间就设为true
  }
  return (
    dateValid &&
    (form.isValid === root.isValid || !form.isValid) &&
    (!form.publishDepartment ||
      form.publishDepartment === "不限" ||
      form.publishDepartment === root.publishDepartment)
  );
}

module.exports = {
  multiplePhraseSplit,
  splicing,
  createFullTextIndex,
  getSearchedRoots,
  formItemFilter,
  getSearchCondition,
  optionalParamValidity,
};
